﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Text;

namespace Atmk.WaterMeter.MIS.Commons.Utils
{
    /// <summary>
    /// 一些对于枚举的操作方法
    /// </summary>
    public class EnumHelper
    {
        ///<summary>
        /// 将枚举转换为Dictionary&lt;枚举项,描述&gt;
        ///</summary>
        ///<param name="enumType"></param>
        ///<returns> Dictionary&lt;枚举项,描述&gt;</returns>
        /// <exception cref="IndexOutOfRangeException">枚举无描述时异常</exception>
        public static Dictionary<string, string> GetEnumDic(Type enumType)
        {
            var dic = new Dictionary<string, string>();
            var fieldinfos = enumType.GetFields();
            foreach (var field in fieldinfos)
            {
                if (!field.FieldType.IsEnum) continue;
                var objs = field.GetCustomAttributes(typeof(DescriptionAttribute), false);
                dic.Add(field.Name, ((DescriptionAttribute) objs[0]).Description);
            }

            return dic;
        }
        /// <summary>
        /// 获取该枚举值的描述
        /// </summary>
        /// <typeparam name="TEnum"></typeparam>
        /// <param name="value"></param>
        /// <returns>枚举值的描述，如果无描述则为string.Empty</returns>
        public static string GetDescriptionByEnum<TEnum>(TEnum value)
        {
            try
            {
                var dic = GetEnumDic(typeof(TEnum));
                return dic[value.ToString()];
            }
            catch (IndexOutOfRangeException)
            {
               return string.Empty;
            }
        }

        /// <summary>
        /// 根据描述，获取第一个与描述一致的枚举值
        /// </summary>
        /// <typeparam name="TEnum">枚举类型</typeparam>
        /// <param name="descriptionText">描述值</param>
        /// <param name="result">返回的枚举值</param>
        /// <returns></returns>
        /// <exception cref="IndexOutOfRangeException">枚举无描述时异常</exception>
        /// <exception cref="ArgumentException">TEnum不是枚举时异常</exception>
        public static bool TryEnumByDescription<TEnum>(string descriptionText, out TEnum result) 
            where TEnum : struct
        {
            var dic = GetEnumDic(typeof(TEnum));
            var enumName = "";
            foreach (var kv in dic)
            {
                if (kv.Value != descriptionText) continue;
                enumName = kv.Key;
                break;
            }
            return Enum.TryParse(enumName, out result);
        }
    }
}